package com.yanqu.road.server.manager.activity.commonteam;

import com.alibaba.fastjson.JSONObject;
import com.yanqu.road.dao.impl.servercenter.ActivityDaoImpl;
import com.yanqu.road.entity.activity.ActivityInfo;
import com.yanqu.road.entity.activity.commonteam.CommonTeamConfigData;
import com.yanqu.road.entity.activity.commonteam.config.ActivityTeamConfig;
import com.yanqu.road.entity.activity.commonteam.data.CommonTeamUserData;
import com.yanqu.road.entity.enums.eActivityType;
import com.yanqu.road.entity.player.UserBaseInfo;
import com.yanqu.road.entity.union.activitygroup.UnionActivityGroup;
import com.yanqu.road.exception.BusinessException;
import com.yanqu.road.logic.config.GameConfig;
import com.yanqu.road.logic.helper.ActivityHelper;
import com.yanqu.road.logic.helper.UnionActivityGroupHelper;
import com.yanqu.road.pb.activity.CommonTeamProto;
import com.yanqu.road.server.CrossBaseServer;
import com.yanqu.road.server.TempCrossMgr;
import com.yanqu.road.server.manager.activity.ActivityMgr;
import com.yanqu.road.server.manager.activity.commonteam.activitytypehandler.CommonTeamActivityTypeStrategy;
import com.yanqu.road.server.manager.activity.commonteam.activitytypehandler.handler.CommonTeamSonHaiStrategy;
import com.yanqu.road.server.manager.activity.commonteam.activitytypehandler.handler.XingYouShanShuiStrategy;
import com.yanqu.road.server.manager.union.activitygroup.Cross2UnionActivityGroupMgr;
import com.yanqu.road.server.manager.user.CrossUserNotifyMgr;
import com.yanqu.road.server.manger.IUserBaseInfoSyncListener;
import com.yanqu.road.server.protocol.GameErrorCode;
import com.yanqu.road.utils.FixSizeLinkedList;
import com.yanqu.road.utils.date.DateHelper;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;

import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;

public class CommonTeamMgr extends TempCrossMgr {

    /**
     * 日志
     */
    private static Logger logger = LogManager.getLogger(CommonTeamMgr.class.getName());

    /**
     * 活动MAP,k:活动ID,k:分组ID
     */
    private static Map<Integer, Map<Integer, CommonTeamActivity>> commonTeamActivityGroupMap = new ConcurrentHashMap<>();

    /**
     * 活动类型策略MAP(该策略map可以灵活处理不同活动类型的特殊处理)
     */
    private static Map<Integer, CommonTeamActivityTypeStrategy> activityTypeStrategyMap = new ConcurrentHashMap<>();
    static {
        activityTypeStrategyMap.put(eActivityType.SonHai.getValue(), new CommonTeamSonHaiStrategy());
        activityTypeStrategyMap.put(eActivityType.XingYouShanShui.getValue(), new XingYouShanShuiStrategy());
    }

    public static Logger getLogger() {
        return logger;
    }

    /**
     * 移除过期活动
     * @return
     * @throws Exception
     */
    @Override
    public boolean removeExpireData() throws Exception {
        Set<Integer> acSet = new HashSet<>();
        long nowTime = System.currentTimeMillis();
        for (Integer activityId : commonTeamActivityGroupMap.keySet()) {
            Map<Integer, CommonTeamActivity> groupActivityMap = commonTeamActivityGroupMap.get(activityId);
            if (groupActivityMap != null) {
                // 展示期过3天后移除内存
                for (CommonTeamActivity activity : groupActivityMap.values()) {
                    if (activity == null || activity.getConfig() == null || activity.getConfig().getActivityInfo() == null ||
                            nowTime > activity.getConfig().getActivityInfo().getEndShowTime() * 1000 + 3 * DateHelper.DAY_MILLIONS) {
                        acSet.add(activityId);
                    }
                }
            }
        }
        for (int activityId : acSet) {
            commonTeamActivityGroupMap.remove(activityId);
        }
        return true;
    }

    @Override
    public boolean init() throws Exception {
        CrossUserNotifyMgr.addSyncListener(new syncHandle());
        return reload();
    }

    //更新下玩家的昵称
    public class syncHandle implements IUserBaseInfoSyncListener {
        @Override
        public void notifySync(UserBaseInfo userBaseInfo, long userId) {
            for (Map.Entry<Integer, Map<Integer, CommonTeamActivity>> entry : commonTeamActivityGroupMap.entrySet()) {
                for (Map.Entry<Integer, CommonTeamActivity> activityEntry : entry.getValue().entrySet()) {
                    CommonTeamActivity value = activityEntry.getValue();
                    CommonTeamUserData userData = value.getUserData(userId);
                    ActivityInfo activityInfo = ActivityMgr.getActivityInfo(value.getConfig().getActivityId());
                    if(userData != null && ActivityMgr.activityInTime(activityInfo)){
                        if(!userBaseInfo.getNickName().equals(userData.getUserName())){
                            userData.setUserName(userBaseInfo.getNickName());
                        }
                    }
                }
            }
        }
    }

    @Override
    public boolean reloadData() throws Exception {
        Map<Integer, ActivityInfo> activityInfoMap = ActivityMgr.getOpenCrossActivityMapByTypes(activityTypeStrategyMap.keySet());
        //活动加载进内存
        for (ActivityInfo activityInfo : activityInfoMap.values()) {
            //活动是否在展示期
            if (!ActivityHelper.activityInShowTime(activityInfo)) {
                continue;
            }
            //判断活动是否需要分组
            if (UnionActivityGroupHelper.needGroup(activityInfo)) {
                //查询活动分组
                Map<Integer, UnionActivityGroup> activityGroupMap = Cross2UnionActivityGroupMgr.getGroupMap(activityInfo.getActivityId());
                if (activityGroupMap == null || activityGroupMap.isEmpty()) {
                    logger.error("通用组队-加载活动-查询活动分组-分组不存在：{}", activityInfo.getActivityId());
                    continue;
                }
                for (UnionActivityGroup activityGroup : activityGroupMap.values()) {
                    if (activityGroup.getCrossServerId() == CrossBaseServer.getInstance().getServerId()) {
                        getActivity(activityGroup.getActivityId(), activityGroup.getGroupId());
                    }
                }
            }else {
                getActivity(activityInfo.getActivityId(), 0);
            }
        }
        return true;
    }

    @Override
    public boolean stop() {
        return true;
    }

    /**
     * 存储数据
     * @return
     */
    @Override
    public boolean save() {
        for (Map<Integer, CommonTeamActivity> commonTeamActivityMap : commonTeamActivityGroupMap.values()) {
            for (CommonTeamActivity activity : commonTeamActivityMap.values()) {
                try {
                    activity.save();
                }catch (Exception e){
                    getLogger().error("CommonTeamMgr activity {} save err", activity.getConfig().getActivityInfo().getActivityId(), e.getCause());
                }
            }
        }
        return true;
    }

    /**
     * 刷新配置
     * @return
     * @throws Exception
     */
    @Override
    public boolean reloadConfig() throws Exception {
        reloadActivityConfig();
        return true;
    }

    /**
     * 刷新活动配置
     */
    public static void reloadActivityConfig() {
        getLogger().info("CommonTeamMgr reloadConfig start");
        for (Map<Integer, CommonTeamActivity> commonTeamActivityMap : commonTeamActivityGroupMap.values()) {
            for (CommonTeamActivity activity : commonTeamActivityMap.values()) {
                CommonTeamConfigData configData = activity.getConfig();
                if (configData == null) {
                    continue;
                }
                ActivityInfo activityInfo = configData.getActivityInfo();
                if (activityInfo == null) {
                    continue;
                }

                //读取活动
                activityInfo = new ActivityDaoImpl().getActivityInfoByActivityId(activityInfo.getActivityId());
                if (activityInfo == null) {
                    continue;
                }
                configData.setActivityInfo(activityInfo);

                if (!ActivityHelper.activityInShowTime(activityInfo)) {
                    continue;
                }
                //构造活动配置
                CommonTeamConfigData newConfigData = getTeamConfigFromDb(activityInfo);
                if (newConfigData == null) {
                    continue;
                }
                //刷新配置信息
                activity.refreshConfig(newConfigData);
                getLogger().info("CommonTeamMgr reloadConfig success,activityId:{}", activityInfo.getActivityId());
            }
        }
        getLogger().info("CommonTeamMgr reloadConfig end");
    }

    /**
     * 获取活动
     * @param activityId
     * @return
     */
    public static CommonTeamActivity getActivity(int activityId, int groupId) {
        Map<Integer, CommonTeamActivity> commonTeamActivityMap = commonTeamActivityGroupMap.get(activityId);
        if (commonTeamActivityMap != null) {
            CommonTeamActivity activityInfo = commonTeamActivityMap.get(groupId);
            if (activityInfo != null) {
                return activityInfo;
            }
        }
        //初始化活动
        return initActivity(activityId, groupId);
    }

    /**
     * 初始化活动
     * @param activityId
     * @return
     */
    private static CommonTeamActivity initActivity(int activityId, int groupId) {
        synchronized (commonTeamActivityGroupMap) {
            Map<Integer, CommonTeamActivity> commonTeamActivityMap = commonTeamActivityGroupMap.computeIfAbsent(activityId, k -> new ConcurrentHashMap<>());
            CommonTeamActivity commonTeamActivity = commonTeamActivityMap.get(groupId);
            if (commonTeamActivity != null) {
                return commonTeamActivity;
            }
            // 读配置 获取活动信息 保证有活动信息
            ActivityInfo activityInfo = ActivityMgr.getActivityInfoMayLoadDB(activityId);
            if (activityInfo == null) {
                return null;
            }
            //不在展示期也不处理了
            if (!ActivityHelper.activityInShowTime(activityInfo)) {
                return null;
            }
            //构造活动配置
            CommonTeamConfigData configData = getTeamConfigFromDb(activityInfo);
            if (configData == null) {
                return null;
            }
            //创建活动
            commonTeamActivity = new CommonTeamActivity(configData, groupId);
            commonTeamActivityMap.put(groupId, commonTeamActivity);
            return commonTeamActivity;
        }
    }

    /**
     * 获取通用组队配置（读DB）
     * @param activityInfo
     * @return
     */
    public static CommonTeamConfigData getTeamConfigFromDb(ActivityInfo activityInfo) {
        int activityId = activityInfo.getActivityId();
        Map<String, ActivityTeamConfig> activityTeamConfigMap = new ActivityDaoImpl().getActivityTeamConfigMap(activityId);
        if (activityTeamConfigMap == null || activityTeamConfigMap.isEmpty()) {
            logger.error("加载通用组队配置-组队配置为找到：{}", activityId);
            return null;
        }
        try {
            CommonTeamConfigData configData = new CommonTeamConfigData();
            configData.setActivityId(activityId);
            configData.setActivityInfo(activityInfo);
            int ingotsNum = activityTeamConfigMap.get("TEAM_CREATE_NEED_INGOTS").getIntValue();
            String teamCost = GameConfig.GAME_MONEY_INGOTS + "=" + ingotsNum;
            configData.setCreateTeamCost(teamCost);
            configData.setCreateNeedIngots(ingotsNum);
            configData.setCreateTeamTime(activityTeamConfigMap.get("TEAM_CREATE_TEAM_TIME").getIntValue());
            configData.setUserNumMax(4);
            configData.setNameLengthMax(activityTeamConfigMap.get("TEAM_NAME_LENGTH_LIMIT").getIntValue());
            configData.setApplyMax(activityTeamConfigMap.get("TEAM_APPLY_MAX_LIMIT").getIntValue());
            configData.setUserApplyMax(activityTeamConfigMap.get("TEAM_USER_APPLY_MAX_LIMIT").getIntValue());
            configData.setJoinCrossTeamFlag(activityTeamConfigMap.get("TEAM_JOIN_KUAFU").getIntValue());
            configData.setJoinCd(activityTeamConfigMap.get("TEAM_JOIN_CD").getIntValue());
            long endTime = activityInfo.getBeginTime() * 1000 + activityTeamConfigMap.get("TEAM_CREATE_TEAM_TIME").getIntValue() * DateHelper.MINUTE_MILLIONS;
            configData.setEndTime(endTime);
            //日志输出一下
            logger.info("加载通用组队配置：" + JSONObject.toJSONString(configData));
            return configData;
        } catch (Exception e) {
            logger.error("加载通用组队配置-报错：{}", e);
        }
        return null;
    }

    /**
     * 判断不在组队期。在组队期就返回错误
     * @param activityId
     * @return
     */
    public static void checkNotInTeamTime(int activityId, int groupId) throws BusinessException {
        CommonTeamActivity activity = getActivity(activityId, groupId);
        if (activity == null) {
            throw new BusinessException(GameErrorCode.E_COMMON_TEAM_TEAM_NAME_EXIST);
        }
        boolean inTeamTime = activity.checkInTeamTime();
        if (inTeamTime) {
            throw new BusinessException(GameErrorCode.E_COMMON_TEAM_ALREADY_IN_TEAM_TIME);
        }
    }

    /**
     * 构造队伍聊天信息
     * @param activityId
     * @param groupId
     * @param userId
     * @param type 0 普通聊天 1加入 2离开 3创建队伍 4协助信息（根据不同类型，扩展协议字段）
     * @param contentType
     * @param content
     * @return
     */
    public static CommonTeamProto.CommonTeamChatMsg.Builder createTeamChatMsg(int activityId, int groupId, long userId, int type, int contentType, String content) {
        //获取活动
        CommonTeamActivity activity = getActivity(activityId, groupId);
        if (activity == null) {
            return null;
        }
        //获取玩家
        CommonTeamUserData userData = activity.getUserData(userId);
        if (userData == null) {
            return null;
        }
        //获取队伍
        CommonTeam team = activity.getTeam(userData.getTeamId());
        if (team == null) {
            return null;
        }
        //构造消息体
        return activity.createTeamChatMsg(userId, type, contentType, content);
    }

    /**
     * 发送队伍聊天信息
     * @param activityId
     * @param groupId
     * @param userId
     * @param msg
     */
    public static void sendTeamChatMsg(int activityId, int groupId, long userId, CommonTeamProto.CommonTeamChatMsg.Builder msg) {
        //获取活动
        CommonTeamActivity activity = getActivity(activityId, groupId);
        if (activity == null) {
            return;
        }
        //获取玩家
        CommonTeamUserData userData = activity.getUserData(userId);
        if (userData == null) {
            return;
        }
        //获取队伍
        CommonTeam team = activity.getTeam(userData.getTeamId());
        if (team == null) {
            return;
        }
        //发送队伍聊天信息
        team.sendTeamChatMsg(msg.build());
    }

    /**
     * 获取玩家活动积分
     * @param activityId
     * @param userId
     * @return
     */
    public static List<Long> getUserActivityScoreList(int activityId, int groupId, long userId) {
        //获取活动
        CommonTeamActivity activityInfo = getActivity(activityId, groupId);
        if (activityInfo == null) {
            return null;
        }
        //获取策略MAP
        CommonTeamActivityTypeStrategy activityTypeStrategy = activityTypeStrategyMap.get(activityInfo.getConfig().getActivityInfo().getType());
        if (activityTypeStrategy == null) {
            return null;
        }
        //获取不同活动类型对应的积分
        return activityTypeStrategy.getUserActivityScoreList(activityId, groupId, userId);
    }

    /**
     * 同意入队后处理
     * @param activityId
     * @param groupId
     * @param teamId
     * @param userData
     */
    public static void agreeJoinTeamAfterHandle(int activityId, int groupId, int teamId, CommonTeamUserData userData, String language) {
        //获取活动
        CommonTeamActivity activityInfo = getActivity(activityId, groupId);
        if (activityInfo == null) {
            return;
        }
        //获取策略MAP
        CommonTeamActivityTypeStrategy activityTypeStrategy = activityTypeStrategyMap.get(activityInfo.getConfig().getActivityInfo().getType());
        if (activityTypeStrategy == null) {
            return;
        }
        try {
            //同意入队后处理
            activityTypeStrategy.agreeJoinTeamAfterHandle(activityId, groupId, teamId, userData, language);
        } catch (BusinessException e) {
            logger.error("通用组队-同意入队后处理-异常：{}", e.getCode());
        }
    }

    /**
     * 退出后处理
     * @param activityId
     * @param groupId
     * @param teamId
     * @param userData
     */
    public static void quitTeamAfterHandle(int activityId, int groupId, int teamId, CommonTeamUserData userData) {
        //获取活动
        CommonTeamActivity activityInfo = getActivity(activityId, groupId);
        if (activityInfo == null) {
            return;
        }
        //获取策略MAP
        CommonTeamActivityTypeStrategy activityTypeStrategy = activityTypeStrategyMap.get(activityInfo.getConfig().getActivityInfo().getType());
        if (activityTypeStrategy == null) {
            return;
        }
        try {
            //退出后处理
            activityTypeStrategy.quitTeamAfterHandle(activityId, groupId, teamId, userData.getUserId());
        } catch (BusinessException e) {
            logger.error("通用组队-退出后处理-异常：{}", e.getCode());
        }
    }



    /**
     * 创建后处理
     * @param activityId
     * @param groupId
     * @param teamId
     * @param userData
     */
    public static void createTeamAfterHandle(int activityId, int groupId, int teamId, CommonTeamUserData userData) {
        //获取活动
        CommonTeamActivity activityInfo = getActivity(activityId, groupId);
        if (activityInfo == null) {
            return;
        }
        //获取策略MAP
        CommonTeamActivityTypeStrategy activityTypeStrategy = activityTypeStrategyMap.get(activityInfo.getConfig().getActivityInfo().getType());
        if (activityTypeStrategy == null) {
            return;
        }
        try {
            //创建后处理
            activityTypeStrategy.createTeamAfterHandle(activityId, groupId, teamId, userData.getUserId());
        } catch (BusinessException e) {
            logger.error("通用组队-创建后处理-异常：{}", e.getCode());
        }
    }

    /**
     * 获取队伍信息，根据玩家ID
     * @param activityId
     * @param groupId
     * @param userId
     * @return
     * @throws BusinessException
     */
    public static CommonTeam getTeamByUserId(int activityId, int groupId, long userId) throws BusinessException {
        CommonTeamActivity activity = getActivity(activityId, groupId);
        if (activity == null) {
            throw BusinessException.newException(GameErrorCode.E_COMMON_TEAM_TEAM_ACTIVITY_NOT_EXIST);
        }
        return activity.getTeamByUserId(userId);
    }

    /**
     * 获取队伍信息，根据队伍ID
     * @param activityId
     * @param groupId
     * @param teamId
     * @return
     */
    public static CommonTeam getTeam(int activityId, int groupId, int teamId) {
        CommonTeamActivity activity = getActivity(activityId, groupId);
        if (activity == null) {
            return null;
        }
        return activity.getTeam(teamId);
    }

    /**
     * 队伍榜单积分变更
     * @param activityId
     * @param groupId
     * @param conditionType
     * @param teamId
     * @param score
     * @param param
     */
    public static void changeTeamRankScore(int activityId, int groupId, int conditionType, int teamId, long score, long param) {
        //判断队伍榜单类型是否正确
        boolean flag = checkTeamRankConditionType(activityId, conditionType);
        if (flag) {
            CommonTeamActivity activity = getActivity(activityId, groupId);
            if (activity != null) {
                activity.changeTeamRankScore(teamId, conditionType, score, param);
            }
        }
    }

    /**
     * 获取队伍榜单类型
     * @param activityId
     * @return
     */
    public static List<Integer> getTeamRankConditionTypes(int activityId) {
        //获取活动
        ActivityInfo activityInfo = ActivityMgr.getActivityInfo(activityId);
        if (activityInfo == null) {
            return null;
        }
        //获取策略MAP
        CommonTeamActivityTypeStrategy activityTypeStrategy = activityTypeStrategyMap.get(activityInfo.getType());
        if (activityTypeStrategy == null) {
            return null;
        }
        //获取不同活动类型对应的榜单类型
        return activityTypeStrategy.getTeamRankConditionTypes();
    }

    /**
     * 判断队伍榜单类型是否正确
     * @param activityId
     * @param conditionType
     * @return
     */
    public static boolean checkTeamRankConditionType(int activityId, int conditionType) {
        List<Integer> conditionTypes = CommonTeamMgr.getTeamRankConditionTypes(activityId);
        if (conditionTypes != null && conditionTypes.contains(conditionType)) {
            return true;
        }
        return false;
    }

    /**
     * 格式化聊天消息
     * @param activityId
     * @param groupId
     * @param chatMsgList
     * @return
     */
    public static FixSizeLinkedList<CommonTeamProto.CommonTeamChatMsg> formatTeamChatMsgList(int activityId, int groupId, FixSizeLinkedList<CommonTeamProto.CommonTeamChatMsg> chatMsgList) {
        //获取活动
        ActivityInfo activityInfo = ActivityMgr.getActivityInfo(activityId);
        if (activityInfo == null) {
            return chatMsgList;
        }
        //获取策略MAP
        CommonTeamActivityTypeStrategy activityTypeStrategy = activityTypeStrategyMap.get(activityInfo.getType());
        if (activityTypeStrategy == null) {
            return chatMsgList;
        }
        return activityTypeStrategy.formatTeamChatMsgList(activityId, groupId, chatMsgList);
    }
}

